import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { User } from 'src/entities/User';
import { UserModelService } from 'src/model/user-model/user-model.service';
import { RedisService } from 'src/redis/redis.service';
import UserInfoDto from './dto/UserInfo.dto';

type U = {[key in keyof User]? : User[key]}

@Injectable()
export class UserService {
    private cacheFields:(keyof User)[] = ['userId', 'openid', 'unionid', 'sessionKey', 'avatar', 'nickname'];
    private cacheKey = '';
    constructor(
        private redis:RedisService,
        private userModelService:UserModelService,
        private configService:ConfigService
    ) {
        this.cacheKey = this.configService.get<string>('cacheKey.user')
    }

    async updateUserInfo(userId:number, params:UserInfoDto) {
        if(Object.keys(params).length == 0) return false
        let user = this.getUserByUserId(userId)
        let updateData:U = {}
        for(let k in params) {
            if(params[k] != user[k]) {
                updateData[k] = params[k]
            }
        }
        if(Object.keys(updateData).length == 0) return true

        this.cacheUser(userId, updateData)

        return this.update(userId, updateData)
    }

    setOpenIdToUserId(openid, userId) {
        this.redis.hset(this.configService.get<string>('cacheKey.openidToUserId'), openid, userId)
    }

    async getUserByUserId(userId:number) {
        let user:U = null
        user = await this.redis.hgetall(this.cacheKey + userId) //缓存没有
        if(!user) {
            user = await this.userModelService.findOne({userId : userId}, this.cacheFields)
            if(user) {
                this.cacheUser(userId, user)
            }
        }

        return user
    }

    async getUserByOpenid(openid:string) {
        let user:U|null = null
        let userId = await this.redis.hget<number>(this.configService.get<string>('cacheKey.openidToUserId'), openid)
        if(userId) {
            user = await this.getUserByUserId(userId)
        }else {
            user = await this.userModelService.findOne({openid : openid}, this.cacheFields)
            if(user) {
                this.cacheUser(user.userId, user)
                this.setOpenIdToUserId(openid, user.userId)
            }
        }

        return user
    }

    update(userId:number, data:U) {
        return this.userModelService.update({userId : userId}, data)
    }

    cacheUser(userId:number, data:U) {
        let tmp:any[] = []
        for(let k in data) {
            tmp.push(k, data[k])
        }

        this.redis.hmset(this.cacheKey + userId, ...tmp) //缓存用户
    }
}
